"""author: wenyao
   data: 2021/11/18
   project: cjh
"""
#引用计数
#python中的每个对象都维护一个引用计数 ob_ref字段
#当有新的引用指向该对象的时候，引用计数+1
#当有无效的引用发生的时候，引用计数-1
#最后引用计数为0，销毁对象

# >>> from sys import getrefcount
# >>> a = 1000
# >>> getrefcount(a)
# 2
# >>> b=a
# >>> getrefcount(a)
# 3
# >>> c = []
# >>> c.append(b)
# >>> getrefcount(a)
# 4
# >>> b = 300
# >>> getrefcount(a)
# 3
# >>> d = 2000
# >>> e = 2000
# >>> getrefcount(d)
# 2
# >>> getrefcount(e)
# 2
# >>> d = e = 600
# >>> getrefcount(d)
# 3


############循环引用
# >>> x = [1]
# >>> y = [2]
# >>> x.append(y)
# >>> y.append(x)
# >>> getrefcount(x)
# 3
# >>> getrefcount(y)
# 3
# >>> del x
# >>> del y

#根据引用计数的规律，出现循环引用的情况，内存是无法通过引用计数来释放
#这种情况就会造成内存泄漏
#内存泄漏：  有一部分没存被占用无法释放，进程又无法访问（占着茅坑不拉屎）
#内存溢出（oom -- out of memory）： 内存不够，程序需要的内存大于系统空闲内存

#垃圾回收
#分代回收 -- 启动垃圾回收的时候确定扫描哪些对象的
#标记清除 -- 主要解决循环引用

#以引用计数为主，分代回收、标记清除为辅的垃圾回收方式，
# 以及对小整型进行缓存和简单字符串驻留的内存池机制

#内存池
#预先创建好一个小整型数池 [-5,256]
# >>> a = 3
# >>> getrefcount(a)
# 48
# >>> a = 1
# >>> getrefcount(a)
# 813
# >>> a = 300
# >>> getrefcount(a)
# 2

#字符串驻留区
#单个字符，创建之后会存放在字符串驻留区
#多个字符，创建之后如果没有特殊字符，就会存放在字符串驻留区
# >>> str1 = "abc xyz"
# >>> str2 = "abc xyz"
# >>> id(str1)
# 140139718054160
# >>> id(str2)
# 140139718054216
# >>> str1 = "abc123"
# >>> str2 = "abc123"
# >>> id(str1)
# 140139718054272
# >>> id(str2)
# 140139718054272
# >>> str1="#"
# >>> str2="#"
# >>> id(str1)
# 140139749007800
# >>> id(str2)
# 140139749007800

####深拷贝与浅拷贝
#只会发生在容器类型里面包含其他可变容器类型的情况

#浅拷贝可能会造成修改拷贝之后的值，会改变原来的值
#深拷贝不会发生这个情况

# >>> a = {"name":"sc", "score":[80,90,100]}
# >>> b = a.copy()
# >>> a
# {'name': 'sc', 'score': [80, 90, 100]}
# >>> b
# {'name': 'sc', 'score': [80, 90, 100]}
# >>> b["score"].append(110)
# >>> b
# {'name': 'sc', 'score': [80, 90, 100, 110]}
# >>> a
# {'name': 'sc', 'score': [80, 90, 100, 110]}
# >>>

#浅拷贝只会拷贝第一层对象的地址
#深拷贝就是拷贝每一层数据
  #使用copy模块的deepcopy函数进行的拷贝就是深拷贝

# >>> b = a.copy()
# >>> a
# {'name': 'sc', 'score': [80, 90, 100]}
# >>> b
# {'name': 'sc', 'score': [80, 90, 100]}
# >>> b["score"].append(110)
# >>> b
# {'name': 'sc', 'score': [80, 90, 100, 110]}
# >>> a
# {'name': 'sc', 'score': [80, 90, 100, 110]}
# >>> id(b["score"])
# 140139748867720
# >>> id(a["score"])
# 140139748867720
# >>> id(a)
# 140139718040528
# >>> id(b)
# 140139718040312
# >>> id(a["name"])
# 140139718054160
# >>> id(b["name"])
# 140139718054160
# >>> import copy
# >>> b = copy.deepcopy(a)   #进行深拷贝
# >>> a
# {'name': 'sc', 'score': [80, 90, 100, 110]}
# >>> b
# {'name': 'sc', 'score': [80, 90, 100, 110]}
# >>> id(a["name"])
# 140139718054160
# >>> id(b["name"])
# 140139718054160
# >>> id(b["score"])
# 140139710604360
# >>> id(a["score"])
# 140139748867720
# >>> b["score"].append(120)
# >>> b
# {'name': 'sc', 'score': [80, 90, 100, 110, 120]}
# >>> a
# {'name': 'sc', 'score': [80, 90, 100, 110]}
#
# >>> lst = [[]]*3
# >>> lst
# [[], [], []]
# >>> lst[0]
# []
# >>> lst[0].append(1)
# >>> lst
# [[1], [1], [1]]
# >>> id(lst[0])
# 140139710605896
# >>> id(lst[1])
# 140139710605896
# >>> id(lst[2])
# 140139710605896
